# 导入User模型
from models.user import User
# 导入原生SQL结果格式化装饰器
from utils.decorators import format_raw_sql_results
# 导入数据库管理器
from utils.db_manager import db_manager

class UserRepository:
    """
    用户数据访问层。
    封装了所有与'users'表相关的数据库操作。
    注意：这里的所有方法都接受一个'session'参数，它们不自己管理事务，
    而是参与到由业务逻辑层（Service）发起的事务中。
    """
    
    def create(self, session, user_data):
        """创建一个新用户。"""
        # 使用字典解包(**user_data)快速创建User实例
        user = User(**user_data)
        # 将新创建的user对象添加到session中，此时它处于'pending'状态
        session.add(user)
        # session.flush()将'pending'状态的对象写入数据库，使其变为'persistent'状态
        # 这时，数据库会为user分配一个ID，但事务尚未提交
        session.flush()
        return user

    def get_by_id(self, session, user_id):
        """根据ID获取用户。"""
        # session.query(User)创建一个查询对象
        # .filter(User.id == user_id)添加查询条件
        # .first()执行查询并返回第一个结果，如果不存在则返回None
        return session.query(User).filter(User.id == user_id).first()

    def update(self, session, user_id, user_data):
        """更新用户信息。"""
        # 首先，根据ID查询到要更新的用户对象
        user = self.get_by_id(session, user_id)
        if user:
            # 遍历传入的更新数据字典
            for key, value in user_data.items():
                # 使用setattr动态地更新user对象的属性
                setattr(user, key, value)
            # flush将更改写入数据库
            session.flush()
        return user

    def delete(self, session, user_id):
        """删除用户。"""
        user = self.get_by_id(session, user_id)
        if user:
            # session.delete()将对象标记为待删除
            session.delete(user)
            return True
        return False

    # 应用我们自定义的装饰器
    @format_raw_sql_results
    def find_users_by_raw_sql(self, username_part):
        """使用原生SQL模糊查询用户。"""
        # 明确指定查询列，避免返回密码等敏感信息
        sql = "SELECT id, username, email, created_at, updated_at FROM users WHERE username LIKE :username_part"
        # 准备SQL参数，使用模糊匹配
        params = {'username_part': f'%{username_part}%'}
        # 调用db_manager执行原生SQL
        result = db_manager.execute_sql(sql, params)
        # fetchall()获取所有查询结果
        # 返回值会被@format_raw_sql_results装饰器处理成字典列表
        return result.fetchall()